home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / ICONX_FO / RDOASGN.C < prev    next >
Text File  |  1990-03-02  |  8KB  |  239 lines

  1. /*
  2.  * File: rdoasgn.c
  3.  *  Contents: doasgn.c
  4.  */
  5.  
  6. #include "::h:config.h"
  7. #include "::h:rt.h"
  8. #include "rproto.h"
  9.  
  10. /*
  11.  * doasgn - assign value of dp2 to variable dp1.
  12.  *  Does the work for asgn, swap, rasgn, and rswap.
  13.  */
  14.  
  15. int doasgn(dp1, dp2)
  16. dptr dp1, dp2;
  17.    {
  18.    register word i1, i2;
  19.    register union block *bp;
  20.    register struct b_table *tp;
  21.    register uword hn;
  22.    int (*putf)();
  23.    int ret_code;
  24.    union block *hook, **slot;
  25.    char sbuf1[MaxCvtLen];
  26.  
  27.    tended[1] = *dp1;
  28.    tended[2] = *dp2;
  29.    ntended = 2;
  30.  
  31. assign:
  32.  
  33.    if (!Tvar(tended[1]))
  34.       *(dptr)((word *)VarLoc(tended[1]) + Offset(tended[1])) = tended[2];
  35.    else switch (Type(tended[1])) {
  36.          case T_Tvsubs:
  37.             /*
  38.              * An assignment is being made to a substring trapped
  39.              *  variable.  The tended descriptors are used as
  40.              *  follows:
  41.              *
  42.              *    tended[1] - the substring trapped variable
  43.              *    tended[2] - the value to assign
  44.              *    tended[3] - the string containing the substring
  45.              *    tended[4] - the substring
  46.              *    tended[5] - the result string
  47.              */
  48.  
  49.             /*
  50.              * Be sure that the value to be assigned is a string.
  51.              */
  52.             ntended = 5;
  53.             if (DeRef(tended[2]) == Error) {
  54.                ntended = 0;
  55.                return Error;
  56.                }
  57.             if (cvstr(&tended[2], sbuf1) == CvtFail) {
  58.                ntended = 0;
  59.                RetError(103, tended[2]);
  60.                }
  61.  
  62.             /*
  63.              * Be sure that the variable in the trapped variable points
  64.              *  to a string.
  65.              */
  66.             tended[3] = BlkLoc(tended[1])->tvsubs.ssvar;
  67.             if (DeRef(tended[3]) == Error) {
  68.                ntended = 0;
  69.                return Error;
  70.                }
  71.             if (!Qual(tended[3])) {
  72.                ntended = 0;
  73.                RetError(103, tended[3]);
  74.                }
  75.             if (strreq(StrLen(tended[3]) + StrLen(tended[2])) == Error)
  76.                return Error;
  77.  
  78.             /*
  79.              * Get a pointer to the substring trapped-variable block and
  80.              *  make i1 a C-style index to the character that begins the
  81.              *  substring.
  82.              */
  83.             bp = BlkLoc(tended[1]);
  84.             i1 = bp->tvsubs.sspos - 1;
  85.  
  86.             /*
  87.              * Make tended[4] a descriptor for the substring.
  88.              */
  89.             StrLen(tended[4]) = bp->tvsubs.sslen;
  90.             StrLoc(tended[4]) = StrLoc(tended[3]) + i1;
  91.  
  92.             /*
  93.              * Make i2 a C-style index to the character after the
  94.              *  substring. If i2 is greater than the length of the
  95.              *  substring, it is an error because the string being
  96.              *  assigned will not fit.
  97.              */
  98.             i2 = i1 + StrLen(tended[4]);
  99.             if (i2 > StrLen(tended[3])) {
  100.                ntended = 0;
  101.                RetError(-205, nulldesc);
  102.                }
  103.  
  104.             /*
  105.              * Form the result string.    First, copy the portion of the
  106.              *  substring string to the left of the substring into the
  107.              *  string space.
  108.              */
  109.             StrLoc(tended[5]) = alcstr(StrLoc(tended[3]), i1);
  110.  
  111.             /*
  112.              * Copy the string to be assigned into the string space,
  113.              *  effectively concatenating it.
  114.              */
  115.             alcstr(StrLoc(tended[2]), StrLen(tended[2]));
  116.  
  117.             /*
  118.              * Copy the portion of the substring to the right of
  119.              *  the substring into the string space, completing the
  120.              *  result.
  121.              */
  122.             alcstr(StrLoc(tended[3]) + i2, StrLen(tended[3]) - i2);
  123.  
  124.             /*
  125.              * Calculate the length of the new string.
  126.              */
  127.             StrLen(tended[5]) = StrLen(tended[3]) - StrLen(tended[4]) +
  128.                StrLen(tended[2]);
  129.             bp->tvsubs.sslen = StrLen(tended[2]);
  130.             tended[1] = bp->tvsubs.ssvar;
  131.             tended[2] = tended[5];
  132.  
  133.             /*
  134.              * Everything is set up for the actual assignment.  Go
  135.              *  back to the beginning of the routine to do it.
  136.              */
  137.             goto assign;
  138.  
  139.          case T_Tvtbl:
  140.             /*
  141.              *
  142.              * The tended descriptors are used as follows:
  143.              *
  144.              *    tended[1] - the table element trapped variable
  145.              *    tended[2] - the value to be assigned
  146.              *    tended[3] - subscripting value
  147.              */
  148.  
  149.             /*
  150.              * Point bp to the trapped-variable block, point tended[3]
  151.              *  to the subscripting value, and point tp to the table-
  152.              *  header block.
  153.              */
  154.             ntended = 3;
  155.             bp = BlkLoc(tended[1]);
  156.  
  157.             if (bp->tvtbl.title == T_Telem) {
  158.                /*
  159.                 * The trapped-variable block already has been
  160.                 *  converted to a table-element block.  Just assign
  161.                 *  to it and return.
  162.                 */
  163.                bp->telem.tval = tended[2];
  164.                ntended = 0;
  165.                return Success;
  166.                }
  167.             tended[3] = bp->tvtbl.tref;
  168.             tp = (struct b_table *)bp->tvtbl.clink;
  169.  
  170.             /*
  171.              * Get the hash number for the subscripting value and
  172.              *  locate the chain that contains the element to which
  173.              *  assignment is to be made.
  174.              */
  175.             hn = bp->tvtbl.hashnum;
  176.             slot = hchain((union block *)tp, hn);
  177.             bp = *slot;
  178.  
  179.             /*
  180.              * Traverse the chain to see if the value is already in the
  181.              *  table.  If it is there, assign to it and return.
  182.              */
  183.             hook = bp;
  184.             while (bp != NULL && bp->telem.hashnum <= hn) {
  185.                if (bp->telem.hashnum == hn &&
  186.                   equiv(&bp->telem.tref, &tended[3])) {
  187.                      bp->telem.tval = tended[2];
  188.                      ntended = 0;
  189.                      return Success;
  190.                      }
  191.                hook = bp;
  192.                bp = bp->telem.clink;
  193.                }
  194.  
  195.             /*
  196.              * The value being assigned is new.  Increment the table
  197.              *  size, convert the table-element trapped-variable block
  198.              *  to a table-element block, and link it into the chain.
  199.              */
  200.             tp->size++;
  201.             if (hook == bp) {        /* it goes at front of chain */
  202.                bp = BlkLoc(tended[1]);
  203.                bp->telem.clink = *slot;
  204.                *slot = bp;
  205.                }
  206.  
  207.             else {            /* it follows hook */
  208.                bp = BlkLoc(tended[1]);
  209.                bp->telem.clink = hook->telem.clink;
  210.                hook->telem.clink = bp;
  211.                }
  212.  
  213.             bp->tvtbl.title = T_Telem;
  214.             bp->telem.tval = tended[2];
  215.             tended[1].dword = D_Telem;
  216.             MMShow(&tended[1], "r");
  217.             if (TooCrowded(tp)) {
  218.                tended[1].dword = D_Table;
  219.                BlkLoc(tended[1]) = (union block *)tp;
  220.                hgrow(&tended[1]);
  221.                }
  222.             ntended = 0;
  223.             return Success;
  224.  
  225.          case T_Tvkywd:
  226.             ntended = 2;
  227.             putf = BlkLoc(tended[1])->tvkywd.putval;
  228.             ret_code = (*putf)(&tended[2], BlkLoc(tended[1]));
  229.             ntended = 0;
  230.             return ret_code;
  231.  
  232.          default:
  233.             syserr("doasgn: illegal trapped variable");
  234.          }
  235.  
  236.    ntended = 0;
  237.    return Success;
  238.    }
  239.